import React, { PureComponent, Fragment } from 'react';
import { connect } from 'dva';
import { routerRedux } from 'dva/router';
import moment from 'moment';
import {
  Row,
  Col,
  Card,
  Form,
  Input,
  Select,
  Icon,
  Button,
  Dropdown,
  Menu,
  InputNumber,
  DatePicker,
  Modal,
  message,
  Badge,
  Divider,
  Tabs,
  Table,
  Radio,
} from 'antd';
import GeneralTableComponent from 'components/GeneralTableComponent';
import PageHeaderLayout from '../../layouts/PageHeaderLayout';
import { TimelineChart, Pie, yuan } from 'components/Charts';
import {
  G2,
  Chart,
  Geom,
  Axis,
  Tooltip,
  Coord,
  Label,
  Legend,
  View,
  Guide,
  Shape,
  Facet,
  Util
} from "bizcharts";
import DataSet from "@antv/data-set";

const TabPane = Tabs.TabPane;
const FormItem = Form.Item;
const RangePicker = DatePicker.RangePicker;
const RadioButton = Radio.Button;
const RadioGroup = Radio.Group;

@connect(({ overdueStatistics, loading }) => ({
  overdueStatistics,
  loading: loading.models.overdueStatistics,
}))
@Form.create()
export default class overdueStatistics extends PureComponent {
  state = {
    status: '',
    tableData: [],
    trendData: [],
    pieData: [],
    //参数部分
    userType: '',
    dateStrings: [],
  };

  componentDidMount() {
    let dateStrings = [moment().subtract(7, 'days').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')],
        userType = 'all-user';
    this.getTableData(dateStrings, userType);
    this.getTrendData(dateStrings, userType);
    this.getPieData(dateStrings, userType);
  }

  getTableData = (_dateStrings, _userType, page) => {
    const { dispatch } = this.props;
    const dateStrings = _dateStrings ? _dateStrings : this.state.dateStrings;
    const userType = _userType ? _userType : this.state.userType;
    const pageNo = page ? page : 1;

    let tableParam = {
      minDateStr: '',
      maxDateStr: '',
      // timeType: '',
      pageSize: 10,
      pageNo: pageNo,
      source: 'up',
      userType: userType,
    };
    tableParam.minDateStr = dateStrings[0];
    tableParam.maxDateStr = dateStrings[1];
    dispatch({
     type: 'overdueStatistics/fetchOverdueCountTable',
     payload: {
       ...tableParam,
     },
    }).then(() => {
      let _srcData = this.props.overdueStatistics.overdueTableData,
          tableData = {
            list: [],
            pagination: {
              current: pageNo,
              total: _srcData.pagination.totalCount,
            }
          };
      if (_srcData.list) {
        switch(userType) {
          case 'all-user':
            _srcData.list.forEach((val, index, arr) => {
              if (index != 0) {
                tableData.list.push({
                  date: val.date,
                  overdueRateEver: val.overdueRateEver,
                  overdueRateNow: val.overdueRateNow,
                  S1_title: val.stageMap.S1.overdueAmount + '/' + val.stageMap.S1.overdueOrderNum,
                  S1_newOld: val.stageMap.S1.newUserPercent + '/' + val.stageMap.S1.oldUserPercent,
                  S2_title: val.stageMap.S2.overdueAmount + '/' + val.stageMap.S2.overdueOrderNum,
                  S2_newOld: val.stageMap.S2.newUserPercent + '/' + val.stageMap.S2.oldUserPercent,
                  S3_title: val.stageMap.S3.overdueAmount + '/' + val.stageMap.S3.overdueOrderNum,
                  S3_newOld: val.stageMap.S3.newUserPercent + '/' + val.stageMap.S3.oldUserPercent,
                  S4_title: val.stageMap.S4.overdueAmount + '/' + val.stageMap.S4.overdueOrderNum,
                  S4_newOld: val.stageMap.S4.newUserPercent + '/' + val.stageMap.S4.oldUserPercent,
                });
              }
            });
            break;
          case 'new-user':
            _srcData.list.forEach((val, index, arr) => {
              if (index != 0) {
                tableData.list.push({
                  date: val.date,
                  overdueRateEver: val.overdueRateEver,
                  overdueRateNow: val.overdueRateNow,
                  S1_title: val.stageMap.S1.overdueAmount + '/' + val.stageMap.S1.overdueOrderNum,
                  S1_newOld: val.stageMap.S1.newUserPercent,
                  S2_title: val.stageMap.S2.overdueAmount + '/' + val.stageMap.S2.overdueOrderNum,
                  S2_newOld: val.stageMap.S2.newUserPercent,
                  S3_title: val.stageMap.S3.overdueAmount + '/' + val.stageMap.S3.overdueOrderNum,
                  S3_newOld: val.stageMap.S3.newUserPercent,
                  S4_title: val.stageMap.S4.overdueAmount + '/' + val.stageMap.S4.overdueOrderNum,
                  S4_newOld: val.stageMap.S4.newUserPercent,
                }); 
              }
            });
            break;
          case 'old-user':
            _srcData.list.forEach((val, index, arr) => {
              if (index != 0) {
                tableData.list.push({
                  date: val.date,
                  overdueRateEver: val.overdueRateEver,
                  overdueRateNow: val.overdueRateNow,
                  S1_title: val.stageMap.S1.overdueAmount + '/' + val.stageMap.S1.overdueOrderNum,
                  S1_newOld:val.stageMap.S1.oldUserPercent,
                  S2_title: val.stageMap.S2.overdueAmount + '/' + val.stageMap.S2.overdueOrderNum,
                  S2_newOld:val.stageMap.S2.oldUserPercent,
                  S3_title: val.stageMap.S3.overdueAmount + '/' + val.stageMap.S3.overdueOrderNum,
                  S3_newOld:val.stageMap.S3.oldUserPercent,
                  S4_title: val.stageMap.S4.overdueAmount + '/' + val.stageMap.S4.overdueOrderNum,
                  S4_newOld:val.stageMap.S4.oldUserPercent,
                });
              }
            });
            break;
          default:
            break;
        }
        this.setState({
          tableData: tableData,
          dateStrings: dateStrings,
          userType: userType
        });
      }
    });
  };

  getTrendData = (_dateStrings, _userType) => {
    const { dispatch } = this.props;
    const dateStrings = _dateStrings ? _dateStrings : this.state.dateStrings;
    const userType = _userType ? _userType : this.state.userType;

    let trendParam = {
      minDateStr: '',
      maxDateStr: '',
      // timeType: '',
      userType: '',
      source: 'up',
    };
    trendParam.minDateStr = dateStrings[0];
    trendParam.maxDateStr = dateStrings[1];
    trendParam.userType = userType ? userType : 'all-user';
    dispatch({
     type: 'overdueStatistics/fetchOverdueCountTrend',
     payload: {
       ...trendParam,
     },
    }).then(() => {
      let originData = this.props.overdueStatistics.overdueTrendData;
      this.setState({
        trendData: originData ? this.formatMapData(originData, 'date') : [],
        dateStrings: dateStrings,
        userType: userType,
      });
    });
  };

  formatMapData = (mapData, xCoordinate) => {
    // 用于将map型数据 { a: { x1: '0', x2: '1', } b: { x1: '2', x2: '3', } }
    // 格式化成 [{ [xCoordinate]: 'x1', a: '0', b: '2' }, { [xCoordinate]: 'x2', a: '1', b: '3'}]
    let formatData = [];
    let pick = {
      maxLength: 0,
      maxName: '',
      keysArray: [],
    };
    //返回数组长度方法
    function _length(obj) {
      let _count = 0;
      for (let key of Object.keys(obj)) {
        _count++;
      }
      return _count;
    };
    //判断数据是否合法
    function _isLegal(val) {
      return !( typeof(val) === "undefined" )
    }
    //找到深度为1的内容最多的那条数据对象
    if (mapData) {
      for (let [key, val] of Object.entries(mapData)) {
        pick.keysArray.push(key);
        if (val && _length(val) > pick.maxLength) {
          [pick.maxLength, pick.maxName] = [_length(val), key]; 
        }
      }
    }
    //以最长的那条数据对象为基础初始化目标数组
    for (let [key, val] of Object.entries(mapData[pick.maxName])) {
      let _buf = {
        [xCoordinate]: key
      }
      pick.keysArray.forEach((val, index, arr) => {
        _buf[val] = ''
      })
      formatData.push(_buf);
    }
    //将所有的数据填充到初始化完毕的目标数组中
    formatData.forEach((_val, _index, _arr) => {
      pick.keysArray.forEach((val, index, arr) => {
        if (_isLegal(mapData[val][_val[xCoordinate]])) {
          _val[val] = mapData[val] ? mapData[val][_val[xCoordinate]] : 0;
        } else {
          _val[val] = 0;
        }
      })
    });
    return formatData
  }

  getPieData = (_dateStrings, _userType) => {
    const { dispatch } = this.props;
    const dateStrings = _dateStrings ? _dateStrings : this.state.dateStrings;
    const userType = _userType ? _userType : this.state.userType;

    let pieParam = {
      minDateStr: '',
      maxDateStr: '',
      // timeType: '',
      userType: '',
      source: 'up',
    };
    pieParam.minDateStr = dateStrings[0];
    pieParam.maxDateStr = dateStrings[1];
    pieParam.userType = userType ? userType : 'all-user';
    dispatch({
     type: 'overdueStatistics/fetchOverdueCountPie',
     payload: {
       ...pieParam,
     },
    }).then(() => {
      let _bufPieData = this.props.overdueStatistics.overduePieData.data;
      let pieData = [{
        x: 'S1',
        y: _bufPieData.S1 ? _bufPieData.S1.overdueAmount : 0
      }, {
        x: 'S2',
        y: _bufPieData.S2 ? _bufPieData.S2.overdueAmount : 0
      }, {
        x: 'S3',
        y: _bufPieData.S3 ? _bufPieData.S3.overdueAmount : 0
      }, {
        x: 'S4',
        y: _bufPieData.S4 ? _bufPieData.S4.overdueAmount : 0
      }];
      this.setState({
        pieData: pieData,
        dateStrings: dateStrings,
        userType: userType,
      });
    });
  };

  handleDateChange = (dates, dateStrings) => {
    this.getTableData(dateStrings);
    this.getTrendData(dateStrings);
    this.getPieData(dateStrings);
  };

  handleRadioChange = (e) => {
    this.getTableData(null, e.target.value);
    this.getTrendData(null, e.target.value);
    this.getPieData(null, e.target.value);
  };

  handleStandardTableChange = (pagination, filtersArg, sorter) => {
    this.getTableData(null, null, pagination.current);
  };

  sumAll = (e) => {
    let _sum = 0;
    if (e) {
      e.forEach((val, index, arr) => {
        _sum += val.y;
      });
    }
    return _sum
  }

  render() {
    const { overdueStatistics: { overdueTableData, overdueTrendData }, loading } = this.props;
    const { 
      status, 
      overdueStatistics, 
      tableData, 
      trendData, 
      pieData, 
      userType
    } = this.state;

    //表头初始化
    let _title = '';
    switch(userType) {
      case 'all-user':
        _title = '新/老';
        break;
      case 'new-user':
        _title = '新用户';
        break;
      case 'old-user':
        _title = '老用户'
        break;
      default:
        break;
    }
    const tableColumns = [
      {
        title: '日期',
        dataIndex: 'date',
        key: 'date',
        render: val => `${val}`
      },
      {
        title: '到期逾期率',
        dataIndex: 'overdueRateEver',
        key: 'overdueRateEver',
        render: val => `${val}`
      },
      {
        title: '当前逾期率',
        dataIndex: 'overdueRateNow',
        key: 'overdueRateNow',
        render: val => `${val}`
      },
      {
        title: 'S1(1-7)',
        dataIndex: 'S1_title',
        key: 'S1_title',
        render: val => `${val}`
      },
      {
        title: _title,
        dataIndex: 'S1_newOld',
        key: 'S1_newOld',
        render: val => `${val}`
      },
      {
        title: 'S2(8-20)',
        dataIndex: 'S2_title',
        key: 'S2_title',
        render: val => `${val}`
      },
      {
        title: _title,
        dataIndex: 'S2_newOld',
        key: 'S2_newOld',
        render: val => `${val}`
      },
      {
        title: 'S3(20>S≥30)',
        dataIndex: 'S3_title',
        key: 'S3_title',
        render: val => `${val}`
      },
      {
        title: _title,
        dataIndex: 'S3_newOld',
        key: 'S3_newOld',
        render: val => `${val}`
      },
      {
        title: 'S4(>30)',
        dataIndex: 'S4_title',
        key: 'S4_title',
        render: val => `${val}`
      },
      {
        title: _title,
        dataIndex: 'S4_newOld',
        key: 'S4_newOld',
        render: val => `${val}`
      },
    ];

    //折线图数据初始化
    const ds = new DataSet();
    const dv = ds.createView().source(trendData);
    dv.transform({
      type: "fold",
      fields: ["S1", "S2", "S3", "S4"],
      // 展开字段集
      key: "city",
      // key字段
      value: "min" // value字段
    });
    const cols = {
      date: {
        range: [0, 1]
      }
    };

    return (
      <PageHeaderLayout title="逾期统计">
        <Card bordered={false}>
          <Row gutter={{ md: 8, lg: 24, xl: 48 }}>
            <Col md={10} sm={12}>
              <RadioGroup onChange={this.handleRadioChange} defaultValue="all-user">
                <RadioButton value="all-user">全部用户</RadioButton>
                <RadioButton value="new-user">新用户</RadioButton>
                <RadioButton value="old-user">老用户</RadioButton>
              </RadioGroup>
            </Col>
            <Col md={6} sm={24} />
            <Col md={8} sm={24}>
              <RangePicker
                ranges={{
                  近7天: [moment().subtract(7, 'days'), moment()],
                  近14天: [moment().subtract(14, 'days'), moment()],
                  近30天: [moment().subtract(30, 'days'), moment()],
                }}
                defaultValue={[moment().subtract(7, 'days'), moment()]}
                onChange={this.handleDateChange}
              />
            </Col>
          </Row>
          <Tabs>
            <TabPane tab="趋势图" key="1">
              <Chart height={400} data={dv} scale={cols} forceFit>
                <Legend />
                <Axis name="date" />
                <Axis name="min" label={{ formatter: val => `${val}` }} />
                <Tooltip crosshairs={{ type: "y" }} />
                <Geom type="line" position="date*min" size={2} color={"city"} />
                <Geom type="point" position="date*min" size={4} shape={"circle"} color={"city"} style={{ stroke: "#fff",  lineWidth: 1 }} />
              </Chart>
            </TabPane>
            <TabPane tab="饼状图" key="2">
              <Pie hasLegend title="逾期金额" subTitle="逾期金额" total={this.sumAll(pieData)} data={pieData} height={294}/>,
            </TabPane>
          </Tabs>

          <GeneralTableComponent
            loading={loading}
            data={tableData}
            columns={tableColumns}
            onChange={this.handleStandardTableChange}
          />
        </Card>
      </PageHeaderLayout>
    );
  }
}
